package networks.client;

import java.util.ArrayList;
import java.util.HashMap;
import networks.event.Delegate;
import networks.protocol.Message;

public class EventManager {

    private HashMap<Byte, Delegate.ActionOne<Message>> _callBackMap;
    private HashMap<String, ArrayList<Delegate.ActionOne<Message>>> _eventMap;

    public EventManager() {
        _callBackMap = new HashMap<Byte, Delegate.ActionOne<Message>>();
        _eventMap = new HashMap<String, ArrayList<Delegate.ActionOne<Message>>>();
    }

    /**
     * Adds callback to callBackMap by id
     * 
     * @param id
     * @param callback
     */
    public void AddCallBack(byte id, Delegate.ActionOne<Message> callback) {
        if (id > 0 && callback != null) {
            _callBackMap.put(id, callback);
        }
    }

    /**
     * Invoke the callback when the server return messge
     * 
     * @param id
     * @param data
     */
    public void InvokeCallBack(byte id, Message msg) {
        if (!_callBackMap.containsKey(id)) {
            return;
        }

        _callBackMap.get(id).Invoke(msg);
        _callBackMap.remove(id);
    }

    /**
     * Adds the event to eventMap by name
     * 
     * @param eventName
     * @param callback
     */
    public void AddOnEvent(String eventName, Delegate.ActionOne<Message> callback) {
        ArrayList<Delegate.ActionOne<Message>> list = _eventMap.get(eventName);
        if (list != null) {
            list.add(callback);
        } else {
            list = new ArrayList<Delegate.ActionOne<Message>>();
            list.add(callback);
            _eventMap.put(eventName, list);
        }
    }

    /**
     * If the event exists,invoke the event when server return messge
     * 
     * @param route
     * @param msg
     */
    public void InvokeOnEvent(String route, Message msg) {
        if (!_eventMap.containsKey(route)) {
            return;
        }

        ArrayList<Delegate.ActionOne<Message>> list = _eventMap.get(route);
        for (Delegate.ActionOne<Message> cb : list) {
            cb.Invoke(msg);
        }
    }

    public void Dispose() {
        dispose(true);
    }

    private void dispose(Boolean disposing) {
        _callBackMap.clear();
        _eventMap.clear();
    }
}
